/**
 *******************************************************************************
 * @file  hc32f160_clk.h
 * @brief This file contains all the functions prototypes of the CLK driver
 *        library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2020-11-27       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by HDSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */
#ifndef __HC32F160_CLK_H__
#define __HC32F160_CLK_H__

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_common.h"
#include "ddl_config.h"

/**
 * @addtogroup HC32F160_DDL_Driver
 * @{
 */

/**
 * @addtogroup DDL_CLK
 * @{
 */

#if (DDL_CLK_ENABLE == DDL_ON)

/*******************************************************************************
 * Global type definitions ('typedef')
 ******************************************************************************/
/**
 * @defgroup CLK_Global_Types CLK Global Types
 * @{
 */
/**
 * @brief  CLK Xtal configuration structure definition
 */
typedef struct
{
    uint8_t u8XtalState;      /*!< The new state of the Xtal.
                                This parameter can be a value of @ref CLK_Xtal_Config   */

    uint8_t u8XtalDrv;        /*!< The Xtal drive ability.
                                This parameter can be a value of @ref CLK_Xtal_Config   */

    uint8_t u8XtalMode;       /*!< The Xtal mode selection osc or exclk.
                                This parameter can be a value of @ref CLK_Xtal_Config   */

    uint8_t u8XtalSupDrv;     /*!< The Xtal super drive on or off.
                                This parameter can be a value of @ref CLK_Xtal_Config   */

    uint8_t u8XtalStb;        /*!< The Xtal stable time selection.
                                This parameter can be a value of @ref CLK_Xtal_Config   */
} stc_clock_xtal_init_t;


/**
 * @brief  CLK XtalStd configuration structure definition
 */
typedef struct
{
    uint8_t u8XtalStdState;         /*!< Specifies the new state of XtalStd.
                                        This parameter can be a value of @ref CLK_XtalStd_Config    */

    uint8_t u8XtalStdExceptionType; /*!< Specifies the XtalStd exception type..
                                        This parameter can be a value of @ref CLK_XtalStd_Config    */

    uint8_t u8XtalStdInt;           /*!< Specifies the XtalStd interrupt on or off.
                                        This parameter can be a value of @ref CLK_XtalStd_Config    */

    uint8_t u8XtalStdRst;           /*!< Specifies the XtalStd reset on or off.
                                        This parameter can be a value of @ref CLK_XtalStd_Config    */
} stc_clock_xtalstd_init_t;

/**
 * @brief  CLK Xtal32 configuration structure definition
 */
typedef struct
{
    uint8_t u8Xtal32State;    /*!< The new state of the Xtal32.
                                This parameter can be a value of @ref CLK_Xtal32_Config     */

    uint8_t u8Xtal32Drv;      /*!< The Xtal32 drive ability.
                                This parameter can be a value of @ref CLK_Xtal32_Config     */

    uint8_t u8Xtal32NF;       /*!< The Xtal32 filter selection.
                                This parameter can be a value of @ref CLK_Xtal32_Config     */
} stc_clock_xtal32_init_t;
/**
 * @}
 */

/*******************************************************************************
 * Global pre-processor symbols/macros ('#define')
 ******************************************************************************/
/**
 * @defgroup CLK_Global_Macros CLK Global Macros
 * @{
 */

/**
 * @defgroup CLK_Xtal_Config Xtal Config
 * @{
 */
#define CLK_XTAL_OFF                (CMU_XTALCR_XTALSTP)
#define CLK_XTAL_ON                 (0x00U)

/**
 * @brief Xtal mode selection osc or exclk
 */

#define CLK_XTAL_MD_OSC             (0x00U)
#define CLK_XTAL_MD_EXT_CLK         (CMU_XTALCFGR_XTALMS)

/**
 * @brief Xtal super driver on or off
 */
#define CLK_XTAL_SUPDRV_ON          (CMU_XTALCFGR_SUPDRV)
#define CLK_XTAL_SUPDRV_OFF         (0x00U)

/**
 * @brief Xtal driver ability
 * @note  High suggest OSC 20MHz, Mid bettween 10~20MHz, Low bettween 4~10MHz, ULow 4MHz.
 */
#define CLK_XTAL_DRV_HIGH           (0x00U)
#define CLK_XTAL_DRV_MID            (CMU_XTALCFGR_XTALDRV_0)
#define CLK_XTAL_DRV_LOW            (CMU_XTALCFGR_XTALDRV_1)
#define CLK_XTAL_DRV_ULOW           (CMU_XTALCFGR_XTALDRV)

/**
 * @brief Xtal stable time selection.
 * @note  a cycle of stable counter = a cycle of Xtal
 */
#define CLK_XTALSTB_2POW8           (0x00U)       /*!< 2^8 * Xtal cycle.  */
#define CLK_XTALSTB_2POW9           (0x01U)       /*!< 2^9 * Xtal cycle.  */
#define CLK_XTALSTB_2POW10          (0x02U)       /*!< 2^10 * Xtal cycle. */
#define CLK_XTALSTB_2POW11          (0x03U)       /*!< 2^11 * Xtal cycle. */
#define CLK_XTALSTB_2POW13          (0x04U)       /*!< 2^13 * Xtal cycle. */
#define CLK_XTALSTB_2POW15          (0x05U)       /*!< 2^15 * Xtal cycle. */
#define CLK_XTALSTB_2POW16          (0x06U)       /*!< 2^16 * Xtal cycle. */
#define CLK_XTALSTB_2POW17          (0x07U)       /*!< 2^17 * Xtal cycle. */
/**
 * @}
 */

/**
 * @defgroup CLK_XtalStd_Config XtalStd Config
 * @{
 */

/**
 * @brief Xtal trouble detection on or off
 */
#define CLK_XTALSTD_OFF             (0x00U)
#define CLK_XTALSTD_ON              (CMU_XTALSTDCR_XTALSTDE)

/**
 * @brief XtalStd mode selection
 */
#define CLK_XTALSTD_EXP_TYPE_RST    (CMU_XTALSTDCR_XTALSTDRIS)
#define CLK_XTALSTD_EXP_TYPE_INT    (0x00U)

/**
 * @brief XtalStd reset on or off
 */
#define CLK_XTALSTD_RST_OFF         (0x00U)
#define CLK_XTALSTD_RST_ON          (CMU_XTALSTDCR_XTALSTDRE)

/**
 * @brief XtalStd interrupt on or off
 */
#define CLK_XTALSTD_INT_OFF         (0x00U)
#define CLK_XTALSTD_INT_ON          (CMU_XTALSTDCR_XTALSTDIE)
/**
 * @}
 */


/**
 * @defgroup CLK_Xtal32_Config Xtal32 Config
 * @{
 */
#define CLK_XTAL32_OFF              (CMU_XTAL32CR_XTAL32STP)
#define CLK_XTAL32_ON               (0x00U)

/**
 * @brief Xtal32 driver ability.
 */
#define CLK_XTAL32_DRV_MID          (0x00U)
#define CLK_XTAL32_DRV_HIGH         (CMU_XTAL32CFGR_XTAL32DRV_0)
#define CLK_XTAL32_DRV_LOW          (CMU_XTAL32CFGR_XTAL32DRV_1)
#define CLK_XTAL32_DRV_ULOW         (CMU_XTAL32CFGR_XTAL32DRV)

/**
 * @brief Xtal32 filtering seletion.
 */
#define CLK_XTAL32_NF_ALL           (0x00U)   /*!< Valid in run,stop,power down all mode. */
#define CLK_XTAL32_NF_RUN           (0x02U)   /*!< Valid in run mode.                     */
#define CLK_XTAL32_NF_NONE          (0x03U)   /*!< Invalid in run,stop,power down mode.   */
/**
 * @}
 */

/**
 * @defgroup CLK_Hrc_Config Hrc Config
 * @{
 */
#define CLK_HRC_OFF                 (CMU_HRCCR_HRCSTP)
#define CLK_HRC_ON                  (0x00U)
/**
 * @}
 */


/**
 * @defgroup CLK_HrcFreq_Sel Hrc Config
 * @{
 */
#define CLK_HRCFREQ_64M             (0x00U)   /*!< ICG.HRCFREQS[3] = 0. */
#define CLK_HRCFREQ_32M             (0x01U)   /*!< ICG.HRCFREQS[3] = 0. */
#define CLK_HRCFREQ_16M             (0x02U)   /*!< ICG.HRCFREQS[3] = 0. */
#define CLK_HRCFREQ_8M              (0x03U)   /*!< ICG.HRCFREQS[3] = 0. */
#define CLK_HRCFREQ_4M              (0x04U)   /*!< ICG.HRCFREQS[3] = 0. */
#define CLK_HRCFREQ_2M              (0x05U)   /*!< ICG.HRCFREQS[3] = 0. */

#define CLK_HRCFREQ_48M             (0x00U)   /*!< ICG.HRCFREQS[3] = 1. */
#define CLK_HRCFREQ_24M             (0x01U)   /*!< ICG.HRCFREQS[3] = 1. */
#define CLK_HRCFREQ_12M             (0x02U)   /*!< ICG.HRCFREQS[3] = 1. */
#define CLK_HRCFREQ_6M              (0x03U)   /*!< ICG.HRCFREQS[3] = 1. */
#define CLK_HRCFREQ_3M              (0x04U)   /*!< ICG.HRCFREQS[3] = 1. */
#define CLK_HRCFREQ_1P5M            (0x05U)   /*!< ICG.HRCFREQS[3] = 1. */
/**
 * @}
 */

/**
 * @defgroup CLK_Lrc_Config Lrc Config
 * @{
 */
#define CLK_LRC_OFF                 (CMU_LRCCR_LRCSTP)
#define CLK_LRC_ON                  (0x00U)
/**
 * @}
 */

/**
 * @defgroup CLK_STB_Flag CLK stable Flags
 * @{
 */
#define CLK_FLAG_HRCSTB             (CMU_OSCSTBSR_HRCSTBF)
#define CLK_FLAG_XTALSTB            (CMU_OSCSTBSR_XTALSTBF)
#define CLK_FLAG_XTAL32STB          (CMU_OSCSTBSR_XTAL32STBF)
/**
 * @}
 */

/**
 * @defgroup CLK_System_Clock_Source System Clock Source
 * @{
 */
#define CLK_SYSCLK_SRC_HRC          (0x00U)
#define CLK_SYSCLK_SRC_XTAL         (0x01U)
#define CLK_SYSCLK_SRC_LRC          (0x02U)
#define CLK_SYSCLK_SRC_XTAL32       (0x03U)
/**
 * @}
 */

/**
 * @defgroup CLK_System_Clock_Divider System clock divider
 * @{
 */
#define CLK_SYSCLK_DIV1             (0x00U)
#define CLK_SYSCLK_DIV2             (0x01U)
#define CLK_SYSCLK_DIV4             (0x02U)
#define CLK_SYSCLK_DIV8             (0x03U)
#define CLK_SYSCLK_DIV16            (0x04U)
#define CLK_SYSCLK_DIV32            (0x05U)
#define CLK_SYSCLK_DIV64            (0x06U)
/**
 * @}
 */

/**
 * @defgroup CLK_HCLK_Divider HCLK divider
 * @{
 */
#define CLK_HCLK_DIV1               (0x00U)
#define CLK_HCLK_DIV2               (0x01U)
#define CLK_HCLK_DIV4               (0x02U)
#define CLK_HCLK_DIV8               (0x03U)
#define CLK_HCLK_DIV16              (0x04U)
#define CLK_HCLK_DIV32              (0x05U)
/**
 * @}
 */

/**
 * @defgroup CLK_MCO_Clock_Source CLK MCO Clock Source
 * @{
 */
#define CLK_MCO_SRC_HRC             (0x00U)
#define CLK_MCO_SRC_LRC             (0x01U)
#define CLK_MCO_SRC_XTAL            (0x02U)
#define CLK_MCO_SRC_XTAL32          (0x03U)
#define CLK_MCO_SRC_SYSCLK          (0x04U)
/**
 * @}
 */

/**
 * @defgroup CLK_MCO_Clock_Prescaler CLK MCO Clock Prescaler
 * @{
 */
#define CLK_MCO_DIV1                (0x00U)
#define CLK_MCO_DIV2                (0x10U)
#define CLK_MCO_DIV4                (0x20U)
#define CLK_MCO_DIV8                (0x30U)
#define CLK_MCO_DIV16               (0x40U)
#define CLK_MCO_DIV32               (0x50U)
#define CLK_MCO_DIV64               (0x60U)
#define CLK_MCO_DIV128              (0x70U)
/**
 * @}
 */

/**
 * @defgroup CLK_FCG_Periph_Control CLK FCG Peripheral function control
 * @{
 */
#define CLK_FCG_ADC                  (CMU_FCG_ADC)
#define CLK_FCG_CTC                  (CMU_FCG_CTC)
#define CLK_FCG_AOS                  (CMU_FCG_AOS)
#define CLK_FCG_DMA                  (CMU_FCG_DMA)
#define CLK_FCG_CRC                  (CMU_FCG_CRC)
#define CLK_FCG_TMRB1                (CMU_FCG_TIMB1)
#define CLK_FCG_TMRB2                (CMU_FCG_TIMB2)
#define CLK_FCG_TMRB3                (CMU_FCG_TIMB3)
#define CLK_FCG_TMRB4                (CMU_FCG_TIMB4)
#define CLK_FCG_TMRB5                (CMU_FCG_TIMB5)
#define CLK_FCG_TMRB6                (CMU_FCG_TIMB6)
#define CLK_FCG_TMRB7                (CMU_FCG_TIMB7)
#define CLK_FCG_TMRB8                (CMU_FCG_TIMB8)
#define CLK_FCG_TMR0                 (CMU_FCG_TIM0)
#define CLK_FCG_RTC                  (CMU_FCG_RTC)
#define CLK_FCG_UART1                (CMU_FCG_UART1)
#define CLK_FCG_UART2                (CMU_FCG_UART2)
#define CLK_FCG_UART3                (CMU_FCG_UART3)
#define CLK_FCG_UART4                (CMU_FCG_UART4)
#define CLK_FCG_I2C                  (CMU_FCG_I2C)
#define CLK_FCG_SPI                  (CMU_FCG_SPI)
#define CLK_FCG_UART5                (CMU_FCG_UART5)
#define CLK_FCG_UART6                (CMU_FCG_UART6)
/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * Global variable definitions ('extern')
 ******************************************************************************/

/*******************************************************************************
  Global function prototypes (definition in C source)
 ******************************************************************************/
/**
 * @addtogroup CLK_Global_Functions
 * @{
 */

void CLK_DeInit(void);

en_result_t CLK_XtalStructInit(stc_clock_xtal_init_t* pstcXtalInit);
en_result_t CLK_XtalInit(const stc_clock_xtal_init_t* pstcXtalInit);
en_result_t CLK_XtalStdStructInit(stc_clock_xtalstd_init_t* pstcXtalStdInit);
en_result_t CLK_XtalStdInit(const stc_clock_xtalstd_init_t* pstcXtalStdInit);

en_result_t CLK_Xtal32StructInit(stc_clock_xtal32_init_t* pstcXtal32Init);
en_result_t CLK_Xtal32Init(const stc_clock_xtal32_init_t* pstcXtal32Init);

en_result_t CLK_HrcFreqConfig(uint8_t u8HrcFreq);

en_result_t CLK_XtalCmd(en_functional_state_t enNewState);
en_result_t CLK_Xtal32Cmd(en_functional_state_t enNewState);
en_result_t CLK_HrcCmd(en_functional_state_t enNewState);
en_result_t CLK_LrcCmd(en_functional_state_t enNewState);

void CLK_SetSysClockSrc(uint8_t u8Src);
void CLK_SetClockDiv(uint8_t u8Div);
void CLK_SetADClockDiv(uint8_t u8ADClockDiv);

uint32_t CLK_GetClockFreq(void);

void CLK_FcgPeriphClockCmd(uint32_t u32FcgPeriph, en_functional_state_t enNewState);

void CLK_MCOConfig(uint8_t u8MCOSrc, uint8_t u8MCODiv);
void CLK_MCOCmd(en_functional_state_t enNewState);

void CLK_ClearXtalStdStatus(void);
en_flag_status_t CLK_GetXtalStdStatus(void);
en_flag_status_t CLK_GetStableStatus(uint8_t u8Flag);

/**
 * @}
 */

#endif /* DDL_CLK_ENABLE */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* __HC32F160_CLK_H__ */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
